import java.io.*;
public class AQ_Main
{
	private static AQ_Field field=null;
	private static AQ_Player[] player=null;
	private static final BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
	private static int read(int n){
		int turn=0;
		try{
			ObjectInputStream record=new ObjectInputStream(new FileInputStream("data/"+Integer.toString(n)+".sav"));
			field=(AQ_Field)record.readObject();
			player=(AQ_Player[])record.readObject();
			turn=(Integer)record.readObject();
			record.close();
		}
		catch(Exception e){
			e.printStackTrace();
		}
	return turn;
	}
	private static void save(int turn, int n)
	{
		try
		{
			ObjectOutputStream record=new ObjectOutputStream(new FileOutputStream("data/"+Integer.toString(n)+".sav"));
			record.writeObject(field);
			record.writeObject(player);
			record.writeObject(turn);
			record.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	private static AQ_Player[] setPlayers() throws IOException
	{
		String input;
		AQ_Player[] p=null;
		int n=0;
		do
		{
			try
			{
				System.out.print("How many players? (2~5, x): ");
				input=reader.readLine();
				
				if(input.equals("x")) 
					System.exit(0);
				
				n=Integer.parseInt(input); // Exception from here.
				
				if(2<=n && n<=5)
					p=new AQ_Player[n];
				
			}catch(NumberFormatException e){}
		}while(p==null);
		
		return p;
	}
	
	public static void main(String[] args) throws IOException
	{
		String input;
		String[] argument=null, input_parts=null;
		int[] winner=null;
		int i=0;
		boolean retrieval=false;
		switch(args.length){
			case 0:
			field=AQ_Field.getSingleInstance("./data/element_card.dat");
			player=setPlayers();
			field.initialize(player);
			break;
			case 1:
			i=read(Integer.parseInt(args[0]));
			retrieval=true;
			break;
		}
		for(int k; (winner=field.result(player))==null; i=(i+1)%player.length)
		{
			if(retrieval) retrieval=false;
			else player[i].add(field.pollBank());
			save(i, 9);
			
			for(;;)
			{
				System.out.println("Field:");
				field.toScreen();
				System.out.printf("Hand card (goal=%s):\n", player[i].goal().toString());
				player[i].toScreen();
				System.out.printf("%dP: ", i+1);
				
				try
				{
					input=reader.readLine();
					input_parts=input.split("\\s+");
					
					if(input_parts.length==1)
					{
						if(input_parts[0].equals("skip")) 
							break;
						else if(input_parts[0].equals("exit")) 
							System.exit(0);
					}
					else if(input_parts.length==2){
						if(input_parts[0].equals("save")){
							int n=Integer.parseInt(input_parts[1]);
							if(n<0 || n>8) System.err.println("Saving number must be 0 to 8.");
							else save(i, n);
						}
					}
					k=Integer.parseInt(input_parts[0]);
					argument=new String[input_parts.length-1];
					
					for(int j=0; j<argument.length; j++) 
						argument[j]=input_parts[j+1];
					
					if(player[i].card(k) instanceof AQ_HandCard.ElementCard && argument.length==1)
					{
						if(argument[0].equals("-r"))
						{
							AQ_HandCard.ElementCard c=(AQ_HandCard.ElementCard)player[i].card(k);
							c.rotate();
						}
					}
					else
					{
						AQ_HandCard c=player[i].poll(k);
						if(c.execute(field, player, argument))
							break;
						player[i].add(k, c);
					}
				}
				catch(Exception e){}   
			}
		}
		System.out.print("Winner");
		
		if(winner.length>=2) 
			System.out.print("s");
		
		System.out.print(":");
		
		for(int j=0; j<winner.length; j++) 
			System.out.printf(" %dP", winner[j]+1);
		System.out.println("");
	}
}
